package cn.lumora.config;

import cn.dev33.satoken.dao.SaTokenDao;
import cn.dev33.satoken.dao.SaTokenDaoRedis;
import cn.dev33.satoken.session.SaSession;
import cn.hutool.json.JSONUtil;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Primary;
import org.springframework.stereotype.Component;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Set;

@Slf4j
@Component("jedisSaTokenDao")
@Primary
public class JedisSaTokenDao extends SaTokenDaoRedis {

    @Autowired
    private JedisPool jedisPool;

    private final ObjectMapper objectMapper = new ObjectMapper();

    // ---- String 读写操作 ----

    @Override
    public String get(String key) {
        try (Jedis jedis = jedisPool.getResource()) {
            return jedis.get(key);
        }
    }

    @Override
    public void set(String key, String value, long timeout) {
        try (Jedis jedis = jedisPool.getResource()) {
            if (timeout > 0) {
                jedis.setex(key, (int) timeout, value);
            } else {
                jedis.set(key, value);
            }
        }
    }

    @Override
    public void update(String key, String value) {
        set(key, value, getTimeout(key));
    }

    @Override
    public void delete(String key) {
        try (Jedis jedis = jedisPool.getResource()) {
            jedis.del(key);
        }
    }

    @Override
    public long getTimeout(String key) {
        try (Jedis jedis = jedisPool.getResource()) {
            return jedis.ttl(key);
        }
    }

    @Override
    public void updateTimeout(String key, long timeout) {
        try (Jedis jedis = jedisPool.getResource()) {
            if (timeout > 0) {
                jedis.expire(key, (int) timeout);
            }
        }
    }


    // ---- Object 读写操作 ----

    @Override
    public Object getObject(String key) {
        try (Jedis jedis = jedisPool.getResource()) {
            String json = jedis.get(key);
            if (json == null) return null;
//            return objectMapper.readValue(json, SaSession.class); // 推荐用 Map 结构通用兼容
            return JSONUtil.toBean(json, SaSession.class);
        } catch (Exception e) {
            log.error("反序列化对象失败：key = {}, 原始 JSON = {}", key, get(key), e);
            return null;
        }
    }

    @Override
    public void setObject(String key, Object object, long timeout) {
        try (Jedis jedis = jedisPool.getResource()) {
            String json = objectMapper.writeValueAsString(object);
            if (timeout > 0) {
                jedis.setex(key, (int) timeout, json);
            } else {
                jedis.set(key, json);
            }
        } catch (Exception e) {
            log.error("序列化对象失败", e);
        }
    }

    @Override
    public void updateObject(String key, Object object) {
        setObject(key, object, getTimeout(key));
    }

    @Override
    public void deleteObject(String key) {
        delete(key);
    }

    @Override
    public long getObjectTimeout(String key) {
        return getTimeout(key);
    }

    @Override
    public void updateObjectTimeout(String key, long timeout) {
        updateTimeout(key, timeout);
    }

    // ---- 批量操作 ----

    @Override
    public List<String> searchData(String prefix, String keyword, int start, int size, boolean sortType) {
        try (Jedis jedis = jedisPool.getResource()) {
            Set<String> keys = jedis.keys(prefix + "*");
            return new ArrayList<>(keys);
        }
    }
}

